package com.zyj.benchmark.sample;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

/**
 * @State(Scope.xxx) 描述了这个类对象的作用域
 */
@Warmup(iterations = 1, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 1, time = 5, timeUnit = TimeUnit.SECONDS)
public class Sample_03_States {


    //这个静态内部类会在Benchmark 各个线程执行之前 初始化, 作为入参
    //所有测试线程各用各的
    @State(Scope.Thread)//不同线程不同的对象
    public static class ThreadState {
        volatile double x = Math.PI;
    }

    //根据main方法, 会启动4个线程去一起执行
    //每个线程的入参都是不同的
    @Benchmark
    public void measureUnshared(ThreadState state) { //每个线程的入参都不同
        state.x++;
    }


    //这个静态内部类会在整个Benchmark启动的时候初始化, 作为入参
    //所有测试线程共享一个实例, 用于测试有状态实例在多线程共享下的性能
    //一般用来测试多线程竞争下的性能
    @State(Scope.Benchmark)//整个测试总共用这一个对象
    public static class BenchmarkState {
        volatile double x = Math.PI;
    }

    //这个依然启动4个线程, 但是入参是同一个实例, 竞争会非常激烈
    @Benchmark
    public void measureShared(BenchmarkState state) {//此次测试所有的线程入参都是一个
        state.x++;
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(Sample_03_States.class.getSimpleName())
                .threads(50)
                .forks(1)
                .build();

        new Runner(opt).run();
    }

}
